#include "Include.h"


vu8 OverVoltageCnt, UnderVoltageCnt, OverCurrentCnt,OverPADtemper_Cnt/*,u8_OverI_S_Cnt*/,IGBT_OvertemperCnt;
vu8 ErrRecoveryTimer;
vu8 Ntc_HotTIME;     // NTC warm-up counter
vu16 u16ErrorBuf = 0;

volatile HW_State_type HW_State_type1;

void ProtectWithAD_Task()//1ms
{
    static vu8 OverIGBTtemper_Cnt = 0;
 
    if (bAD_DataReady == 1) // A set of AD data collection completed
    {
        //---- Over Voltage Detect ----//
        if (AD_Vac >= C_MaxVol)
        {
            if (OverVoltageCnt < C_OverVoltageCnt_TH)
            {
                OverVoltageCnt++; // count the time of OverVoltage
            }
            else
            {
                bErrOverVoltage = 1;
                ErrRecoveryTimer = C_ErrRecoveryTime;
            }
        }
        else if (OverVoltageCnt > 0)
        {
            OverVoltageCnt--;
        }

        if (1 == bErrOverVoltage)
        {
            IGBT_Off();
            bErrPowerOff = 1;
            u16ErrorBuf |= 0b0000000000000001; //1

            IH_Status_App.flagBit.error = ERROR_OVP;
        }

        //---- Low Voltage Detect ----//
        if (AD_Vac < C_MinVol)
        {
            if (UnderVoltageCnt < C_UnderVoltageCnt_TH)
            {
                UnderVoltageCnt++; // count the time of UnderVoltage
            }
            else
            {
                bErrUnderVoltage = 1;
                ErrRecoveryTimer = C_ErrRecoveryTime;
            }
        }
        else if (UnderVoltageCnt > 0)
        {
            UnderVoltageCnt--;
        }

        if (1 == bErrUnderVoltage)
        {
            IGBT_Off();
            bErrPowerOff = 1;
            u16ErrorBuf |= 0b0000000000000010;//2
            IH_Status_App.flagBit.error = ERROR_UVP;
        }
        //---- Over Current Detect ----//
        if (AD_Iac >= C_AD_MaxCurrent)
        {
            if (OverCurrentCnt < C_OverCurrentCnt_TH)
                OverCurrentCnt++; // count the time of OverCurrentCnt
            else
            {
                bErrOverCurrent = 1;
                ErrRecoveryTimer = C_ErrRecoveryTime;
            }
        }
        else if (OverCurrentCnt > 0)
        {
            OverCurrentCnt--;
        }
        
    	 if (1 == bErrOverCurrent)
        {
        	IGBT_Off();
            bErrPowerOff = 1;
            IH_Status_App.flagBit.error = ERROR_OCP;
            u16ErrorBuf |= 0b0000000000001000;//8
        }

        //---- Error Processing ----//ntc 
        if ((1 == bIgbtNtcError) || (1 == bPanNtcError) || (1 == bErrOverCurrent))
        {
            bErrPowerOff = 1;

			if (bMachineOnState == ON) // Switch machine flag
            {
                PowerOffProc();
            }
            
            if (1 == bErrOverCurrent)
            {
                IH_Status_App.flagBit.error = ERROR_OCP;
                u16ErrorBuf |= 0b0000000000001000;
            }

            if (1 == bIgbtNtcError)
            {	//igbt
                if (Temp_IGBT >= C_T_IGBT_NTC_OPENCIRCUIT) // NTC open circuit
                {
                    IH_Status_App.flagBit.error = ERROR_IGBT_NTC; // igbt NTC malfunction
                }
                if (Temp_IGBT <= C_T_IGBT_NTC_SHORTCIRCUIT) // NTC Short circuit
                {
                    IH_Status_App.flagBit.error = ERROR_IGBT_NTC; // igbt NTC malfunction
                }
                u16ErrorBuf |= 0b0000000000010000;
            }
            if (1 == bPanNtcError)
            {
                if (Temp_PAN >= C_T_PAD_NTC_OPENCIRCUIT) // NTC open circuit
                {
                    IH_Status_App.flagBit.error = ERROR_PAN_NTC; // error code
                }
                if (Temp_PAN <= C_T_PAD_NTC_SHORTCIRCUIT) // NTC Short circuit
                {
                    IH_Status_App.flagBit.error = ERROR_PAN_NTC; // error code
                }
                u16ErrorBuf |= 0b0000000000100000;
            }

        }

        //---- Over temperature Detect ----//

        if (bMachineOnState == ON) // Stove surface overheated
        {
            if (Temp_PAN <= PAN_NTC_OVERTEMP_POWOFF && (Temp_PAN > C_T_PAD_NTC_SHORTCIRCUIT)) // Over temperature and not short circuit
            {
                if (OverPADtemper_Cnt < C_OvertemperCnt)
                {
                    OverPADtemper_Cnt++; // count the time of Overtemp
                }
                else
                {
                    bErrPAD_Otemper = 1;
                    u16ErrorBuf |= 0b0000000010000000;
                }
            }
            else if (OverPADtemper_Cnt > 0)
            {
                OverPADtemper_Cnt--;
            }
        }  

        if (1 == bErrPAD_Otemper)
        {
            IGBT_Off();
            bErrPowerOff = 1;
            u16ErrorBuf |= 0b0000000100000000;
            IH_Status_App.flagBit.error = ERROR_PAN_OVER_TMP;
            
            if (Temp_PAN >= C_T_PAD_RECOVER)	//If the temperature is below this value, the error will be resolved
            {	
                bErrPAD_Otemper = 0;
                bErrPowerOff = 0;
                OverPADtemper_Cnt = 0;
                IH_Status_App.flagBit.error = ERROR_NO;
            }
        }
        
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       
        if (Temp_IGBT <= IGBT_NTC_OVERTEMP_POWOFF && (Temp_IGBT > C_T_IGBT_NTC_SHORTCIRCUIT)) // Over temperature and not short circuit
        {
            if (OverIGBTtemper_Cnt < C_OvertemperCnt)
            {
                OverIGBTtemper_Cnt++; 
            }
            else
            {
                bErrIGBT_Otemper = 1;
                u16ErrorBuf |= 0b0000001000000000;//error code
            }
        }
        else if (OverIGBTtemper_Cnt > 0)
        {
            OverIGBTtemper_Cnt--;
        }
        if (1 == bErrIGBT_Otemper)
        {
            IGBT_Off();
            bErrPowerOff = 1;
            IH_Status_App.flagBit.error = ERROR_IGBT_OVER_TMP;
             u16ErrorBuf |= 0b0100000000000000;//error code
            if (Temp_IGBT >= C_T_IGBT_RECOVER)//After the temperature of the IGBT drops, it returns to normal operation
            {
                bErrIGBT_Otemper = 0;
                bErrPowerOff = 0;
                OverIGBTtemper_Cnt = 0;
                bIGBT_HTemp_PowDrop = 0;// 0:normal 1:limit power
                IH_Status_App.flagBit.error = ERROR_NO;
            }
        }
    }
}


void Protect_ErrRecovery() // Error recovery
{
    if (ErrRecoveryTimer > 0)
    {
        ErrRecoveryTimer--;
        if (ErrRecoveryTimer == 0)
        {
            if (1 == bErrOverCurrent) // Overcurrent
            {
                bErrOverCurrent = 0;
                IH_Status_App.flagBit.error = ERROR_NO;
            }
            //----------------Flag bit that will be restored after normal work----------
            if ((1 == bErrOverVoltage) || (1 == bErrUnderVoltage))
            {
                bErrOverVoltage = 0;
                bErrUnderVoltage = 0;
                bErrPowerOff = 0; // Clear the shutdown flag and restore the original state
                IH_Status_App.flagBit.error = ERROR_NO;
            }
            if (1 == bSurgeHW || 1 == bOverCurrentHW) // Surge or the first hardware overcurrent within 3s
            {
                bSurgeHW = 0;
                bOverCurrentHW = 0;
                bErrPowerOff = 0; // Clear the shutdown flag and restore the original state
            }
            //-------------Other flags--------------------------
            if ((1 == bOverVoltageHW)) // IGBT VCE
            {
                bOverVoltageHW = 0;
                _rlbf = 0;
            }
        }
    }
}

void Surge_Protect()
{
    if (1 == bSurgeHW)
    {
        IGBT_Off();
        bErrPowerOff = 1;
        u16ErrorBuf |= 0b0000010000000000;
    }

    if (1 == bOverCurrentHW)
    {
        IGBT_Off();
        bErrPowerOff = 1;
        u16ErrorBuf |= 0b0001000000000000;
    }
}

void NTC_Detect() // ----NTC open circuit or short circuit Detect-----
{
	static vu8 u8_Ntc_IgbtError_Cnt = 0;
	static vu8 u8_Ntc_PadError_Cnt = 0;

   	if (bMachineOnState == ON) 
    {
        if (Ntc_HotTIME < C_2Min) // Warm up 2min		
        {
            Ntc_HotTIME++;
        }
        else
        {
            //	----------------------IGBT NTC trouble
            if ((Temp_IGBT >=C_T_IGBT_NTC_OPENCIRCUIT) || (Temp_IGBT <= C_T_IGBT_NTC_SHORTCIRCUIT)) 
            {
                if (u8_Ntc_IgbtError_Cnt < C_NTC_TIMEOUT)
                {
                    u8_Ntc_IgbtError_Cnt++;
                }
                else
                {
                    bIgbtNtcError = 1; // IGBT NTC Open circuit or short circuit
                }
            }
            else
            {
                u8_Ntc_IgbtError_Cnt = 0;
            }
            //-------------------------PAD NTC trouble
            if ((Temp_PAN >= C_T_PAD_NTC_OPENCIRCUIT) || (Temp_PAN <= C_T_PAD_NTC_SHORTCIRCUIT))
            {
                if (u8_Ntc_PadError_Cnt < C_NTC_TIMEOUT)
                {
                    u8_Ntc_PadError_Cnt++;
                }
                else
                {
                    bPanNtcError = 1; // PAD NTC Open circuit or short circuit
                }
            }
            else
            {
                u8_Ntc_PadError_Cnt = 0;
            }
        }
    }
    else
    {
        Ntc_HotTIME = 0;
        bIgbtNtcError = 0;
        bPanNtcError = 0;
        u8_Ntc_IgbtError_Cnt = 0;
        u8_Ntc_PadError_Cnt = 0;
    }
}
//---- Over temperature Detect ----



void OverTEMP_PowerDrop()
{
    //-------------------------------
    if (bMachineOnState == ON)
    {
    	if(Temp_IGBT <= IGBT_NTC_OVERTEMP_LIMIT_POW)//  IGBT Over temperature limiting power
    	{
            if (IGBT_OvertemperCnt < C_NTC_TIMEOUT)//5s
            {
                IGBT_OvertemperCnt++;
            }
            else
            {
                bIGBT_HTemp_PowDrop = 1;
            }	
    	}    	
    	else if( (bIGBT_HTemp_PowDrop == 1) && (Temp_IGBT >= C_T_IGBT_RECOVER) )
        {
        	
            if (IGBT_OvertemperCnt < C_30SEC)//30s
            {
                IGBT_OvertemperCnt++;
            }
            else
            {
                bIGBT_HTemp_PowDrop = 0;
            }	
            
        }
        else if(IGBT_OvertemperCnt > 0)	
        {
        	IGBT_OvertemperCnt--;	
        }
    }
    else
    {
        IGBT_OvertemperCnt = 0;
    }
}